<?php

declare(strict_types=1);

namespace Hesb\LaravelPlus\Annotation;

use Attribute;
use Hesb\LaravelPlus\AnnotationCollector;
use Hesb\LaravelPlus\ReflectionManager;
use ReflectionClass;
use PhpDocReader\AnnotationException as DocReaderAnnotationException;
use Throwable;
use Zenith\LaravelPlus\Attributes\Autowired;
use Zenith\LaravelPlus\Exceptions\AnnotationException;

#[Attribute(Attribute::TARGET_PROPERTY)]
class Inject extends AbstractAnnotation
{
    public function __construct(public ?string $value = null, public bool $required = true)  {
    }

    public function collectProperty(string $className, ?string $target): void
    {
//        var_dump($className,$target);
//        $reflectionClazz = new ReflectionClass($className);
//        foreach ($reflectionClazz->getProperties() as $property) {
//            $autowired = $property->getAttributes(Inject::class);
//            var_dump($autowired);
////            if ($autowired) {
////                $property->setValue($this, app()->make($property->getType()->getName()));
////            }
////            $values = $property->getAttributes(Value::class);
////            if (isset($values[0])) {
////                $property->setValue($this, Config::get(($values[0])->newInstance()->pattern));
////            }
//        }
//
//        AnnotationCollector::collectProperty($className, $target, static::class, $this);
//
//
//

        try {
            if (is_null($this->value)) {
                $reflectionClass = ReflectionManager::reflectClass($className);

                $reflectionProperty = $reflectionClass->getProperty($target);

                $this->value = $reflectionProperty->getType()->getName();

//                $autowired = $reflectionProperty->getAttributes(Inject::class);
//                if ($autowired) {
//                    $reflectionProperty->setValue($instance, app()->make($this->value));
//                }

//
//                $reflectionProperty->setAccessible(true); // 如果属性是受保护的或私有的，需要先设置为可访问
//                $reflectionProperty->setValue($instance, app ($this->value));
            }
            if (empty($this->value)) {
                throw new AnnotationException("The @Inject value is invalid for {$className}->{$target}");
            }
            AnnotationCollector::collectProperty($className, $target, static::class, $this);
        } catch (AnnotationException $exception) {
            if ($this->required) {
                throw new AnnotationException($exception->getMessage());
            }
            $this->value = '';
        } catch (Throwable $exception) {
            throw new AnnotationException("The @Inject value is invalid for {$className}->{$target}. Because {$exception->getMessage()}");
        }
    }
}
